package com.zs.basic.runoob

/**
 * Kotlin 泛型
 * @description
 * @author madison
 * @date 2021/6/4 09:41
 *
 */

class Box<T>(t: T) {
    var value = t
}

val box = Box<Int>(1)

// 或者
//val box = Box(1)

fun <T> boxIn(value: T) = Box(value)

// 以下都是合法语句
val box4 = boxIn<Int>(1)
val box5 = boxIn(1)     // 编译器会进行类型推断

fun <T> doPrintln(content: T) {
    when (content) {
        is Int -> println("整型数字为 $content")
        is String -> println("字符串转换为大写：${content.uppercase()}")
        else -> println("T 不是整型，也不是字符串")
    }
}

//泛型约束
fun <T : Comparable<T>> sort(list: List<T>) {
    // ……
}

//默认的上界是 Any?。
//对于多个上界约束条件，可以用 where 子句：
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
        where T : CharSequence,
              T : Comparable<T> {
    return list.filter { it > threshold }.map { it.toString() }
}

//型变
class Runnbo<out A>(val a: A) {
    fun foo(): A {
        return a
    }
}

//星号投射
//Function<*, String> , 代表 Function<in Nothing, String> ;
//Function<Int, *> , 代表 Function<Int, out Any?> ;
//Function<, > , 代表 Function<in Nothing, out Any?> .
//注意: 星号投射与 Java 的原生类型(raw type)非常类似, 但可以安全使用

fun main() {
    var boxInt = Box<Int>(10)
    var boxString = Box<String>("Runbbo")

    println(boxInt.value)
    println(boxString.value)

    val age = 23
    val name = "zs"
    val bool = true
    doPrintln(age)
    doPrintln(name)
    doPrintln(bool)

    sort(listOf(1, 2, 3)) // OK。Int 是 Comparable<Int> 的子类型
//    sort(listOf(HashMap<Int,String>())) // 错误：HashMap<Int, String> 不是 Comparable<HashMap<Int, String>> 的子类型

    var strCo = Runnbo("a")
    var anyCo = Runnbo<Any>("b")
    anyCo = strCo
    println(anyCo.foo())
}